#include "mainwindow.h"
#include <QLabel>
#include <QGridLayout>
#include <QMessageBox>
#include <cstdlib>
#include <ctime>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), score(0)
{
    setWindowTitle("2048");
    newGame();
    initializeBoard();
    drawBoard();
    generateRandomTile();
    checkGameOver();
     updateBoard();
}

MainWindow::~MainWindow()
{
}

void MainWindow::initializeBoard()
{
    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            board[i][j] = 0;
            tiles[i][j] = nullptr;
        }
    }
}

void MainWindow::drawBoard()
{
    QWidget *centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);

    QGridLayout *gridLayout = new QGridLayout(centralWidget);

    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            tiles[i][j] = new QLabel("", this);
            tiles[i][j]->setAlignment(Qt::AlignCenter);
            tiles[i][j]->setStyleSheet("QLabel { background-color: #eee4da; border-radius: 10px; border: 2px solid #bbada0; font: bold 24px;}");
            gridLayout->addWidget(tiles[i][j], i, j);
        }
    }

    centralWidget->setLayout(gridLayout);
}

void MainWindow::newGame()
{
    initializeBoard();
    score = 0;
}

void MainWindow::generateRandomTile()
{
    QList<QPair<int, int>> emptyCells;

    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            if (board[i][j] == 0) {
                emptyCells.append(QPair<int, int>(i, j));
            }
        }
    }

    if (emptyCells.isEmpty()) {
        checkGameOver();
        return;
    }

    int randomIndex = rand() % emptyCells.size();
    QPair<int, int> randomCell = emptyCells[randomIndex];
    int value = 2; // Always generate 2 for simplicity

    board[randomCell.first][randomCell.second] = value;
    tiles[randomCell.first][randomCell.second]->setText(QString::number(value));
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_W:
    case Qt::Key_Up:
        moveTiles(0); // Move up
        break;
    case Qt::Key_A:
    case Qt::Key_Left:
        moveTiles(1); // Move left
        break;
    case Qt::Key_S:
    case Qt::Key_Down:
        moveTiles(2); // Move down
        break;
    case Qt::Key_D:
    case Qt::Key_Right:
        moveTiles(3); // Move right
        break;
    default:
        break;
    }
}

void MainWindow::moveTiles(int direction)
{
    bool moved = false;

    switch (direction) {
    case 0: // Up
        for (int j = 0; j < BOARD_SIZE; ++j) {
            for (int i = 1; i < BOARD_SIZE; ++i) {
                if (board[i][j] != 0) { // 当前格子不为空
                    int k = i;
                    while (k > 0 && (board[k - 1][j] == 0 || board[k - 1][j] == board[i][j])) {
                        if (board[k - 1][j] == 0) { // 上方格子为空，则向上移动
                            std::swap(board[k][j], board[k - 1][j]);
                            --k;
                            moved = true;
                        } else if (board[k - 1][j] == board[i][j]) { // 上方格子与当前格子值相同，则合并
                            board[k - 1][j] *= 2;
                            board[k][j] = 0;
                            score += board[k - 1][j];
                            moved = true;
                            break;
                        }
                    }
                }
            }
        }
        break;

    case 1: // Left
        for (int i = 0; i < BOARD_SIZE; ++i) {
            for (int j = 1; j < BOARD_SIZE; ++j) {
                if (board[i][j] != 0) { // 当前格子不为空
                    int k = j;
                    while (k > 0 && (board[i][k - 1] == 0 || board[i][k - 1] == board[i][j])) {
                        if (board[i][k - 1] == 0) { // 左侧格子为空，则向左移动
                            std::swap(board[i][k], board[i][k - 1]);
                            --k;
                            moved = true;
                        } else if (board[i][k - 1] == board[i][j]) { // 左侧格子与当前格子值相同，则合并
                            board[i][k - 1] *= 2;
                            board[i][k] = 0;
                            score += board[i][k - 1];
                            moved = true;
                            break;
                        }
                    }
                }
            }
        }
        break;

    case 2: // Down
        for (int j = 0; j < BOARD_SIZE; ++j) {
            for (int i = BOARD_SIZE - 2; i >= 0; --i) {
                if (board[i][j] != 0) { // 当前格子不为空
                    int k = i;
                    while (k < BOARD_SIZE - 1 && (board[k + 1][j] == 0 || board[k + 1][j] == board[i][j])) {
                        if (board[k + 1][j] == 0) { // 下方格子为空，则向下移动
                            std::swap(board[k][j], board[k + 1][j]);
                            ++k;
                            moved = true;
                        } else if (board[k + 1][j] == board[i][j]) { // 下方格子与当前格子值相同，则合并
                            board[k + 1][j] *= 2;
                            board[k][j] = 0;
                            score += board[k + 1][j];
                            moved = true;
                            break;
                        }
                    }
                }
            }
        }
        break;

    case 3: // Right
        for (int i = 0; i < BOARD_SIZE; ++i) {
            for (int j = BOARD_SIZE - 2; j >= 0; --j) {
                if (board[i][j] != 0) { // 当前格子不为空
                    int k = j;
                    while (k < BOARD_SIZE - 1 && (board[i][k + 1] == 0 || board[i][k + 1] == board[i][j])) {
                        if (board[i][k + 1] == 0) { // 右侧格子为空，则向右移动
                            std::swap(board[i][k], board[i][k + 1]);
                            ++k;
                            moved = true;
                        } else if (board[i][k + 1] == board[i][j]) { // 右侧格子与当前格子值相同，则合并
                            board[i][k + 1] *= 2;
                            board[i][k] = 0;
                            score += board[i][k + 1];
                            moved = true;
                            break;
                        }
                    }
                }
            }
        }
        break;

    default:
        break;
    }

    if (moved) {
        generateRandomTile();
         updateBoard();
    }
}

void MainWindow::updateBoard()
{
    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            // 更新每个方块上的数字文本
            tiles[i][j]->setText(QString::number(board[i][j]));
        }
    }
}


bool MainWindow::canMove()
{
    // Check if there are any empty cells
    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            if (board[i][j] == 0) {
                return true; // There is an empty cell
            }
        }
    }

    // Check if there are any adjacent cells with the same value
    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            if ((i < BOARD_SIZE - 1 && board[i][j] == board[i + 1][j]) ||
                (j < BOARD_SIZE - 1 && board[i][j] == board[i][j + 1])) {
                return true; // There are adjacent cells with the same value
            }
        }
    }

    return false; // No empty cells and no adjacent cells with the same value
}


bool MainWindow::checkGameOver()
{
    // Check if there are any empty cells
    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            if (board[i][j] == 0) {
                return false; // Still have empty cells, game can continue
            }
        }
    }

    // Check if there are any adjacent cells with the same value
    for (int i = 0; i < BOARD_SIZE; ++i) {
        for (int j = 0; j < BOARD_SIZE; ++j) {
            if ((i < BOARD_SIZE - 1 && board[i][j] == board[i + 1][j]) ||
                (j < BOARD_SIZE - 1 && board[i][j] == board[i][j + 1])) {
                return false; // Still have adjacent cells with the same value, game can continue
            }
        }
    }

    // No empty cells and no adjacent cells with the same value, game over
    return true;
}




